package util

import (
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"net/http"
	"time"
)

type JWTClaims struct {
	ID int `json:"user_id"`
	jwt.StandardClaims
}

var skipPaths = []string{
	"/api/login",
	"/api/answer",
	"/api/get_q",
	"/api/admin/share",
}

const SECRET = "hanlinyuan_12345_hello"

func GetIdOfToken(tokenString string) int {
	token, err := jwt.ParseWithClaims(tokenString, &JWTClaims{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(SECRET), nil // 在这里你应该使用加密的密钥
	})
	if err != nil {
		println(err.Error())
		return -1
	}
	if claims, ok := token.Claims.(*JWTClaims); ok && token.Valid {
		return claims.ID
	}
	return -1
}

func GetToken(userId int) string {
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, JWTClaims{
		ID: userId,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: time.Now().Add(time.Hour * 24 * 30 * 12 * 10).Unix(),
		},
	})
	tokenString, err := token.SignedString([]byte(SECRET))
	if err != nil {
		println(err.Error())
		return ""
	}
	return tokenString
}

func JWTAuthMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		for _, path := range skipPaths {
			if path == c.FullPath() {
				c.Next()
				return
			}
		}
		tokenString := c.Request.Header.Get("token")
		if tokenString == "" {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "未鉴权", "code": -1})
			return
		}

		token, err := jwt.ParseWithClaims(tokenString, &JWTClaims{}, func(token *jwt.Token) (interface{}, error) {
			return []byte(SECRET), nil // 在这里你应该使用加密的密钥
		})

		if err != nil {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "未鉴权", "code": -1})
			println(err.Error())
			return
		}

		if claims, ok := token.Claims.(*JWTClaims); ok && token.Valid {
			c.Set("user_id", claims.ID)
			c.Next()
		} else {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "未鉴权", "code": -1})
			return
		}
	}
}
